/*==============================================================================
        This header includes everything that could be used frequently.
        Currently header contains Vector, Color classes and some global
        functions (ex. randomInt()).
==============================================================================*/

#ifndef COMMON_H
#define COMMON_H

#include <string>

/*==============================================================================
                              Globals
==============================================================================*/
#define APP_NAME "AVis"
#define WINDOW_WIDTH 640
#define WINDOW_HEIGHT 480

// Must be GLFW_WINDOW or GLFW_FULLSCREEN
#define WINDOW_MODE GLFW_FULLSCREEN
#define LOG_FILENAME  "avis.log"
#define PI 3.141592653f

// Default output rate
const int OUTPUTRATE = 48000;
// Max length of spectrum arrray
const int SPECTRUMSIZE = 2048;
// The amplitude of sprectrum
const float SPECTRUMRANGE = float(OUTPUTRATE) / 2.0f;
// defines maximum countable frequency
const float MAXFREQ = 1500.0f;
const int MAXOCTAVE = 6;

// Tells equalizer effect history length and disappearance speed
const int HISTORY_LEN = 25;
const int HISTORY_SPEED = 30;

static const std::string note_name[12] = 
{
	"C ", "C#", "D ", "D#", "E ", "F ", "F#", "G ", "G#", "A ", "A#", "B "
};

/*==============================================================================
         Vector class - lets you describe mathematical 2D vector
==============================================================================*/

class Vector2
{
public:
	// Coordinates in x and y planes
	float x, y;

	Vector2();
	Vector2(const Vector2 &a);
	Vector2(float x, float y);
	~Vector2();

	// Arithmetic operations
	Vector2 operator =(const Vector2&);
	Vector2 operator +(const Vector2&) const;
	Vector2 operator -(const Vector2&) const;
	Vector2 operator +=(const Vector2&);
	Vector2 operator -=(const Vector2&);
	Vector2 operator *=(const float);
	Vector2 operator /=(const float);
	Vector2 operator *(const float) const;
	Vector2 operator /(const float) const;

	// Rotates vector by given angle
	void Rotate(float angle);
	// Returns rotated vector
	Vector2 GetRotated(float angle) const;
	// Returns length of vector
	float length() const;
	
};

#define NULL_VECTOR2 Vector2(0.0f, 0.0f)

/*==============================================================================
		Color class - lets you comfortably describe any RGB color.
==============================================================================*/

class Color
{
public:
	// Color bits: r - red, g - green, b - blue, a - alpha
	// Values are in range [0; 255]
	unsigned char r, g, b, a;

	Color();
	Color(const Color &c);
	Color(unsigned char r, unsigned char g, unsigned char b, unsigned char a);
	~Color();

	// Arithmetic operations
	Color operator +(const Color&) const;
	Color operator -(const Color&) const;
	Color operator *(const Color&) const;
	Color operator /(const Color&) const;
	Color operator =(const Color&);
	Color operator +=(const Color&);
	Color operator -=(const Color&);
	Color operator *=(const Color&);
	Color operator /=(const Color&);

	// Convert color bits to range [0.0; 1.0]
	void Normalize(float& rf, float& gf, float& bf, float& af) const;
};

#define COLOR_TRANSPARENT Color(0, 0, 0, 0)
#define COLOR_RED Color(185, 0, 0, 255)
#define COLOR_WHITE Color(255, 255, 255, 255)
#define COLOR_BLACK Color(0, 0, 0, 255)
#define COLOR_YELLOW Color(255, 255, 0, 255)

/*==============================================================================
							HSV color class
==============================================================================*/

class ColorHSV
{
public:
	// h = hue, s = saturation, v = value, a = alpha
	// Values are in range [0; 1]
	float h, s, v, a;

	ColorHSV();
	ColorHSV(const ColorHSV &c);
	ColorHSV(float h, float s, float v, float a);
	~ColorHSV();

	// Arithmetic operations
	ColorHSV operator +(const ColorHSV&);
	ColorHSV operator -(const ColorHSV&);
	ColorHSV operator *(const ColorHSV&);
	ColorHSV operator /(const ColorHSV&);
	ColorHSV operator =(const ColorHSV&);
	ColorHSV operator +=(const ColorHSV&);
	ColorHSV operator -=(const ColorHSV&);
	ColorHSV operator *=(const ColorHSV&);
	ColorHSV operator /=(const ColorHSV&);

};

/*==============================================================================
							Log file functions
==============================================================================*/

void LOG_INIT();
void LOG_ERROR(std::string error_msg);
void LOG_INFO(std::string info_msg);
void LOG_CLOSE();


/*==============================================================================
	Common functions - used frequently in all program (ex. randomInt())
==============================================================================*/

// Returns random integer or float number
int RandomInt(int min, int max);
float RandomFloat();
float RandomFloat(float min, float max);

// Returns min or max of two numbers
float Min(float a, float b);
float Max(float a, float b);

// Linear interpolation, smooth step algorithms
float Lerp(float min, float max, float x);
float UnLerp(float min, float max, float x);
float SmoothStep(float min, float max, float x);

// Counts dot product of two given vectors
float VectorDot(const Vector2& a, const Vector2& b);

// Returns value from normalized float to byte (range: [0; 255] )
unsigned char FloatToByte(float f);
// Convert HSV color to RGB
Color ToRGB(ColorHSV& hsv);
// Convert RGB color to HSV
ColorHSV ToHSV(Color& rgb);
// Return RGB color of the note
Color NoteColor(std::string note);
// Use linear interpolation on color
Color ColorLerp(Color col1, Color col2, float t);

// Convert angle from degrees to radians
float DegToRad(float degrees);
// Returns value in range [0; 1]
float Normalize(float value, float max_value);

#endif // COMMON_H
